#include <GL/gl.h>
#include <GL/glu.h>
#include "mainwindow.h"
#include "SDL_GL.h"

static GLboolean should_rotate = GL_TRUE;

static void quit_SDL( int code )
{
    SDL_Quit( );

    exit( code );
}

/* 设置OPENGL的相关属性 */
static void setup_opengl( int width, int height )
{
    /* 比率,宽度除以高度 */
    float ratio = (float) width / (float) height;

    /*
        控制两点间其他点颜色的过渡模式
        GL_SMOOTH是平滑过渡，表现出来的是渐变
        GL_FLAT是以指定的抹一点的单一颜色绘制其他所有点
    */
    //glShadeModel( GL_FLAT );
    glShadeModel( GL_SMOOTH );

    glCullFace( GL_BACK );
    //glCullFace(GL_FRONT);
    //glCullFace(GL_FRONT_AND_BACK);
    glFrontFace( GL_CCW );
    glEnable( GL_CULL_FACE );

    glClearColor( 0.5, 0.5, 0.5, 0.5 );

    glViewport( 0, 0, width, height );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );

    gluPerspective( 60.0, ratio, 1.0, 1024.0 );
}

static void handle_key_down( SDL_keysym* keysym )
{
    switch ( keysym->sym )
    {
    case SDLK_ESCAPE:
        quit_SDL( 0 );
        break;

    case SDLK_SPACE:
        should_rotate = !should_rotate;
        break;

    default:
        break;
    }

}

static void process_events( void )
{
    SDL_Event event;

    while ( SDL_PollEvent( &event ) )
    {

        switch ( event.type )
        {
        case SDL_KEYDOWN:
            handle_key_down( &event.key.keysym );
            break;

        case SDL_QUIT:
            quit_SDL( 0 );
            break;
        }

    }

}

static void draw_scren(void)
{
    static float angle = 0.0f;

    static GLfloat v0[] = { -1.0f, -1.0f,  1.0f};
    static GLfloat v1[] = { 1.0f, -1.0f,  1.0f};
    static GLfloat v2[] = { 1.0f,  1.0f,  1.0f};
    static GLfloat v3[] = { -1.0f,  1.0f,  1.0f};
    static GLfloat v4[] = { -1.0f, -1.0f, -1.0f};
    static GLfloat v5[] = { 1.0f, -1.0f, -1.0f};
    static GLfloat v6[] = { 1.0f,  1.0f, -1.0f};
    static GLfloat v7[] = { -1.0f,  1.0f, -1.0f};
    static GLubyte red[]    = {255, 0, 0, 255};
    static GLubyte green[]  = {0, 255, 0, 255};
    static GLubyte blue[]   = {0, 0, 255, 255};
    static GLubyte white[]  = {255, 255, 255, 255};
    static GLubyte yellow[] = {0, 255, 255, 255};
    static GLubyte black[]  = {0, 0, 0, 255};
    static GLubyte orange[] = {255, 255, 0, 255};
    static GLubyte purple[] = {255, 0, 255, 0};

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(0.0, 0.0, -4.0);

    glRotatef(angle, 1.0, 2.0, 0.0);

    if (should_rotate)
    {
        if (++angle > 360.0f)
        {
            angle = 0.0f;
        }
    }

    /* 立方体有6个面，下面的绘制把每个面分成两个三角形来渲染的，所以做了12组操作 */
    glBegin(GL_TRIANGLES);
    glColor4ubv( red );
    glVertex3fv( v0 );
    glColor4ubv( green );
    glVertex3fv( v1 );
    glColor4ubv( blue );
    glVertex3fv( v2 );

    glColor4ubv( red );
    glVertex3fv( v0 );
    glColor4ubv( blue );
    glVertex3fv( v2 );
    glColor4ubv( white );
    glVertex3fv( v3 );

    glColor4ubv( green );
    glVertex3fv( v1 );
    glColor4ubv( black );
    glVertex3fv( v5 );
    glColor4ubv( orange );
    glVertex3fv( v6 );

    glColor4ubv( green );
    glVertex3fv( v1 );
    glColor4ubv( orange );
    glVertex3fv( v6 );
    glColor4ubv( blue );
    glVertex3fv( v2 );

    glColor4ubv( black );
    glVertex3fv( v5 );
    glColor4ubv( yellow );
    glVertex3fv( v4 );
    glColor4ubv( purple );
    glVertex3fv( v7 );

    glColor4ubv( black );
    glVertex3fv( v5 );
    glColor4ubv( purple );
    glVertex3fv( v7 );
    glColor4ubv( orange );
    glVertex3fv( v6 );

    glColor4ubv( yellow );
    glVertex3fv( v4 );
    glColor4ubv( red );
    glVertex3fv( v0 );
    glColor4ubv( white );
    glVertex3fv( v3 );

    glColor4ubv( yellow );
    glVertex3fv( v4 );
    glColor4ubv( white );
    glVertex3fv( v3 );
    glColor4ubv( purple );
    glVertex3fv( v7 );

    glColor4ubv( white );
    glVertex3fv( v3 );
    glColor4ubv( blue );
    glVertex3fv( v2 );
    glColor4ubv( orange );
    glVertex3fv( v6 );

    glColor4ubv( white );
    glVertex3fv( v3 );
    glColor4ubv( orange );
    glVertex3fv( v6 );
    glColor4ubv( purple );
    glVertex3fv( v7 );

    glColor4ubv( green );
    glVertex3fv( v1 );
    glColor4ubv( red );
    glVertex3fv( v0 );
    glColor4ubv( yellow );
    glVertex3fv( v4 );

    glColor4ubv( green );
    glVertex3fv( v1 );
    glColor4ubv( yellow );
    glVertex3fv( v4 );
    glColor4ubv( black );
    glVertex3fv( v5 );

    glEnd();

    SDL_GL_SwapBuffers();
}


/* SDL线程里面的主循环 */
int sdl_main_loop(void *window)
{
    const SDL_VideoInfo *info = NULL;
    int width   = 0;
    int height  = 0;
    int bpp     = 0;
    int flags   = 0;

    QWidget *screen = (QWidget*)window;

    char winID[32] = {0};

    sprintf(winID, "SDL_WINDOWID=0x%lx", (long unsigned int)screen->winId());
    SDL_putenv(winID);

    /* 初始化SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Video initialization failed: %s\n",
                SDL_GetError());
    }

    info = SDL_GetVideoInfo( ); /* 获取视频硬件的相关信息，主要为了获得bpp */

    if ( !info )
    {
        fprintf( stderr, "Video query failed: %s\n",
                 SDL_GetError( ) );
        quit_SDL( 1 );
    }

    width   = screen->width();
    height  = screen->height();
 //   width   = 400;
 //   height  = 400;
    bpp = info->vfmt->BitsPerPixel;

    /* 设置属性，RGB的大小和位深，开启双缓冲 */
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

    /* 设置视频属性， 这是为了创建一个OPENGL渲染的上下文 */
    flags = SDL_OPENGL;


    if ( SDL_SetVideoMode( width, height, bpp, flags ) == 0 )
    {
        fprintf( stderr, "Video mode set failed: %s\n",
                 SDL_GetError( ) );
        quit_SDL( 1 );
    }


    setup_opengl( width, height );

    while ( 1 )
    {
        /* process_events(); */
        draw_scren();
        /* SDL_Delay(5); */
    }

    return 0;
}
